package com.qzsoft.zhjd.laboratory.modules.asphaltCombustionFurnace.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qzsoft.jeemis.common.exception.RenException;
import com.qzsoft.zhjd.common.components.BaseServiceComponent;
import com.qzsoft.zhjd.common.utils.ZhjdIotUtils;
import com.qzsoft.zhjd.laboratory.modules.asphaltCombustionFurnace.entity.AsphaltCombustionFurnaceEntity;
import com.qzsoft.zhjd.laboratory.modules.asphaltCombustionFurnace.entity.AsphaltCombustionFurnaceResEntity;
import com.qzsoft.zhjd.laboratory.modules.asphaltCombustionFurnace.entity.DDLHBurnerProtocolParser;
import com.qzsoft.zhjd.laboratory.modules.asphaltCombustionFurnace.mapper.AsphaltCombustionFurnaceMapper;
import com.qzsoft.zhjd.laboratory.modules.asphaltCombustionFurnace.service.AsphaltCombustionFurnaceResService;
import com.qzsoft.zhjd.laboratory.modules.asphaltCombustionFurnace.service.AsphaltCombustionFurnaceService;
import com.qzsoft.zhjd.laboratory.modules.common.ByteUtils;
import com.qzsoft.zhjd.laboratory.modules.errorRecord.service.ErrorRecordService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Slf4j
@Service("asphaltCombustionFurnaceService")
public class AsphaltCombustionFurnaceServiceImpl extends ServiceImpl<AsphaltCombustionFurnaceMapper, AsphaltCombustionFurnaceEntity> implements AsphaltCombustionFurnaceService {

    @Autowired
    private AsphaltCombustionFurnaceMapper asphaltCombustionFurnaceMapper;

    @Autowired
    private BaseServiceComponent baseServiceComponent;

    @Autowired
    private AsphaltCombustionFurnaceResService asphaltCombustionFurnaceResService;

    @Autowired
    private ErrorRecordService errorRecordService;

    private static Map<String, String> currentMap = new HashMap<>();

    //燃烧炉
    private static final String TYPE_RSL = "RSL";

    /**
     * 列表
     */
    @Override
    public IPage<JSONObject> queryPage(Map<String, Object> params) {
        IPage<AsphaltCombustionFurnaceEntity> page = baseServiceComponent.getPage(params, AsphaltCombustionFurnaceEntity.class);
        return asphaltCombustionFurnaceMapper.queryPage(page, params);
    }

    /**
     * 信息
     *
     * @return AsphaltCombustionFurnaceEntity
     */
    @Override
    public AsphaltCombustionFurnaceEntity getInfo(String id) {
        return getById(id);
    }

    /**
     * 保存
     */
    @Override
    public void saveData(AsphaltCombustionFurnaceEntity asphaltCombustionFurnace) {
        save(asphaltCombustionFurnace);
    }

    /**
     * 修改
     */
    @Override
    public void updateData(AsphaltCombustionFurnaceEntity asphaltCombustionFurnace) {
        updateById(asphaltCombustionFurnace);
    }

    /**
     * 删除单条数据
     *
     * @param id
     */
    @Override
    public void deleteOneData(String id) {
        removeById(id);
    }

    /**
     * 删除
     */
    @Override
    public void deleteData(List<String> ids) {
        removeByIds(ids);
    }


    /**
     * 解析燃烧法沥青含量测定仪（燃烧炉）数据
     *
     * @param resData  试验结果数据
     * @param deviceId 试验设备id
     */
    @Override
    public void parsingData(String resData, String deviceId) {
        Date nowDate = new Date();
        try {
            List<String> dataList = ZhjdIotUtils.analyzeExperimentalData(resData);
            //如果数据以00开头，可能设备刚开机或重启，表示一次新的实验开始
            if (StringUtils.equals(dataList.get(0), "00")) {
                currentMap.remove(deviceId);
            }

            //验证位不进行校验
            int i = 4;
            //试验数据
            if (StringUtils.equals(ZhjdIotUtils.DATA_TYPE_TEST, dataList.get(i))) {
                AsphaltCombustionFurnaceEntity entity = new AsphaltCombustionFurnaceEntity();
                entity.setDeviceId(deviceId);
                if (currentMap.get(deviceId) == null) {
                    AsphaltCombustionFurnaceResEntity resEntity = new AsphaltCombustionFurnaceResEntity();
                    resEntity.setDeviceId(deviceId);
                    asphaltCombustionFurnaceResService.save(resEntity);
                    currentMap.put(deviceId, resEntity.getId());
                }
                //设置实验结果数据id
                entity.setResId(currentMap.get(deviceId));
                entity.setOriginalData(resData);
                entity.setCreateTime(nowDate);
                i++;
                entity.setFlag(dataList.get(i));

                // 将16进制转换为10进制数据，不含（0x）
                // 初始重量WEIGHT1，4字节无符号数，高字节在前，单位g，包括1位小数；
                i++;
                entity.setOriginalWeight(ZhjdIotUtils.hexToOnePoint(dataList.get(i) + dataList.get(i + 1) + dataList.get(i + 2) + dataList.get(i + 3)));

                //实时重量WEIGHT2，4字节无符号数，高字节在前，单位g，包括1位小数；
                i += 4;
                entity.setRealTimeWeight(ZhjdIotUtils.hexToOnePoint(dataList.get(i) + dataList.get(i + 1) + dataList.get(i + 2) + dataList.get(i + 3)));

                i += 4;
                entity.setRealTimeTemp(ZhjdIotUtils.hexToOnePoint(dataList.get(i) + dataList.get(i + 1)));

                i += 2;
                entity.setMin(Integer.parseInt(dataList.get(i), 16));
                i++;
                entity.setSecond(Integer.parseInt(dataList.get(i), 16));
                save(entity);
                //结果数据
            } else if (StringUtils.equals(ZhjdIotUtils.DATA_TYPE_RES, dataList.get(i))) {
                AsphaltCombustionFurnaceResEntity resEntity = new AsphaltCombustionFurnaceResEntity();
                resEntity.setId(currentMap.get(deviceId));
                currentMap.remove(deviceId);
                resEntity.setDeviceId(deviceId);
                resEntity.setOriginalData(resData);
                resEntity.setCreateTime(nowDate);

                // 将16进制转换为10进制数据，不含（0x）
                // 初始重量WEIGHT1，4字节无符号数，高字节在前，单位g，包括1位小数；
                i++;
                resEntity.setOriginalWeight(ZhjdIotUtils.hexToOnePoint(dataList.get(i) + dataList.get(i + 1) + dataList.get(i + 2) + dataList.get(i + 3)));

                //实时重量WEIGHT2，4字节无符号数，高字节在前，单位g，包括1位小数；
                i += 4;
                resEntity.setRealTimeWeight(ZhjdIotUtils.hexToOnePoint(dataList.get(i) + dataList.get(i + 1) + dataList.get(i + 2) + dataList.get(i + 3)));

                i += 4;
                resEntity.setRealTimeTemp(ZhjdIotUtils.hexToOnePoint(dataList.get(i) + dataList.get(i + 1)));

                i += 2;
                resEntity.setMin(Integer.parseInt(dataList.get(i), 16));
                i++;
                resEntity.setSecond(Integer.parseInt(dataList.get(i), 16));

                asphaltCombustionFurnaceResService.saveOrUpdate(resEntity);
            } else {
                throw new RenException("燃烧法沥青含量测定仪（燃烧炉）数据解析异常：" + resData);
            }
        } catch (Exception e) {
            errorRecordService.saveErrorData(ZhjdIotUtils.ASPHALT_COMBUSTION_FURNACE, deviceId, resData);
            throw new RenException("数据解析异常");
        }
    }

    /**
     * {
     * "shiYangZhongLiang": 12.3,//试样重量
     * "sunShiZhongLiang": 12.3,//损失重量
     * "xiuZhengXiShu": 12.3,//修正系数
     * "liQingHanLiang": 12.3,//沥青含量
     * "youShiBi": 12.3,//油石比
     * "guoCheng1": "0,12.3;1,23.4;2,34.5",//时间温度图
     * "guoCheng2": "0,12.3;1,23.4;2,34.5"//时间损失重量图
     * }
     *
     * @param json
     */
    @Override
    public void dataEntry(JSONObject json) {
        String type = json.getString("type");
        String deviceId = json.getString("deviceId");
        if (StrUtil.isBlank(deviceId)) {
            throw new RuntimeException();
        }
        String data = json.getString("data");
        if (StrUtil.isBlank(data)) {
            errorRecordService.saveErrorData(ZhjdIotUtils.ASPHALT_COMBUSTION_FURNACE, deviceId, json.toJSONString());
            throw new RuntimeException();
        }
        if (StrUtil.equals(TYPE_RSL, type)) {
            Date now = new Date();
            AsphaltCombustionFurnaceResEntity resEntity = new AsphaltCombustionFurnaceResEntity();
            resEntity.setOriginalData(json.toJSONString());
            resEntity.setCreateTime(now);
            resEntity.setShiYangZhongLiang(json.getString("shiYangZhongLiang"));
            resEntity.setSunShiZhongLiang(json.getString("sunShiZhongLiang"));
            resEntity.setXiuZhengXiShu(json.getString("xiuZhengXiShu"));
            resEntity.setYouShiBi(json.getString("youShiBi"));
            resEntity.setGuoCheng1(json.getString("guoCheng1"));
            resEntity.setGuoCheng2(json.getString("guoCheng2"));
            resEntity.setDeviceId(deviceId);
            asphaltCombustionFurnaceResService.saveOrUpdate(resEntity);
        } else {
            errorRecordService.saveErrorData(ZhjdIotUtils.ASPHALT_COMBUSTION_FURNACE, deviceId, json.toJSONString());
            throw new RuntimeException();
        }
    }

    /**
     * 解析数据
     * <p>
     * 北京大地龙华科技 - 燃烧法沥青含量测定仪（燃烧炉）HYRS-6
     *
     * @param rawDataStr 原始数据
     * @param deviceId   设备ID
     * @return
     * @since 20251106
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String parsingDataDDLH(String rawDataStr, String deviceId) {

        Date now = new Date();

        byte[] bytes = ByteUtils.hexStringToBytes(rawDataStr);

        DDLHBurnerProtocolParser protocolParser = null;
        try {
            protocolParser = DDLHBurnerProtocolParser.parseFrame(bytes);
        } catch (IllegalArgumentException e) {
            log.error("解析失败(大地龙华-燃烧炉[HYRS-6]) rawData：{} >>> Error：{}", rawDataStr, e.getMessage(), e);
        }

        // 判断是否有实验结果数据！
        Optional.ofNullable(protocolParser).ifPresent(protocol -> {
            DDLHBurnerProtocolParser.TestResult testResult = protocol.getTestResult();
            if (testResult == null) {
                // 代表没有实验结果数据！跳过即可！
                return;
            }

            // 数据拷贝一下
            AsphaltCombustionFurnaceResEntity entity = new AsphaltCombustionFurnaceResEntity();
            // entity.setId(deviceId);
            entity.setDeviceId(deviceId);
            // entity.setFlag(null);
            entity.setOriginalWeight(BigDecimal.valueOf(testResult.getOriginalWeight()));

            entity.setMin(testResult.getMinute());
            entity.setSecond(testResult.getSecond());
            entity.setCreateTime(now);
            entity.setOriginalData(rawDataStr);
            entity.setShiYangZhongLiang(Double.toString(testResult.getOriginalWeight()));
            entity.setSunShiZhongLiang(Double.toString(testResult.getLossWeight()));
            entity.setXiuZhengXiShu(Double.toString(testResult.getCompensateFactor()));

            entity.setYouShiBi(Double.toString(testResult.getOilStoneRatio()));
            entity.setAsphaltContent(Double.toString(testResult.getAsphaltContent()));

            asphaltCombustionFurnaceResService.saveOrUpdate(entity);

        });
        // TODO：此处返回 确认的数据，不确定是否会对 仪器显示结果的影响！
        return ByteUtils.bytesToHexString(DDLHBurnerProtocolParser.ACK_HEX);
    }

    /**
     * 解析燃烧法沥青含量测定仪（燃烧炉）数据
     *
     * @param resData  试验结果数据
     * @param deviceId 试验设备id
     */
    @Deprecated
    public void parsingDataOld(String resData, String deviceId) {
        Date nowDate = new Date();
        try {
            List<String> dataList = ZhjdIotUtils.analyzeExperimentalData(resData);
            //如果数据以00开头，可能设备刚开机或重启，表示一次新的实验开始
            if (StringUtils.equals(dataList.get(0), "00")) {
                currentMap.remove(deviceId);
            }

            //验证位不进行校验
            int i = 4;
            //试验数据
            if (StringUtils.equals(ZhjdIotUtils.DATA_TYPE_TEST, dataList.get(i))) {
                AsphaltCombustionFurnaceEntity entity = new AsphaltCombustionFurnaceEntity();
                entity.setDeviceId(deviceId);
                if (currentMap.get(deviceId) == null) {
                    AsphaltCombustionFurnaceResEntity resEntity = new AsphaltCombustionFurnaceResEntity();
                    resEntity.setDeviceId(deviceId);
                    asphaltCombustionFurnaceResService.save(resEntity);
                    currentMap.put(deviceId, resEntity.getId());
                }
                //设置实验结果数据id
                entity.setResId(currentMap.get(deviceId));
                entity.setOriginalData(resData);
                entity.setCreateTime(nowDate);
                i++;
                entity.setFlag(dataList.get(i));

                // 将16进制转换为10进制数据，不含（0x）
                // 初始重量WEIGHT1，4字节无符号数，高字节在前，单位g，包括1位小数；
                i++;
                String originalWeight = "" + Integer.parseInt(dataList.get(i), 16) + Integer.parseInt(dataList.get(i + 1), 16) + Integer.parseInt(dataList.get(i + 2), 16) + Integer.parseInt(dataList.get(i + 3), 16);
                entity.setOriginalWeight(ZhjdIotUtils.subByDecimalPlaces(1, originalWeight));

                //实时重量WEIGHT2，4字节无符号数，高字节在前，单位g，包括1位小数；
                i += 4;
                String realTimeWeight = "" + Integer.parseInt(dataList.get(i), 16) + Integer.parseInt(dataList.get(i + 1), 16) + Integer.parseInt(dataList.get(i + 2), 16) + Integer.parseInt(dataList.get(i + 3), 16);
                entity.setRealTimeWeight(ZhjdIotUtils.subByDecimalPlaces(1, realTimeWeight));

                i += 2;
                String realTimeTemp = "" + Integer.parseInt(dataList.get(i), 16) + Integer.parseInt(dataList.get(i + 1), 16);
                entity.setRealTimeTemp(ZhjdIotUtils.subByDecimalPlaces(1, realTimeTemp));

                i += 2;
                entity.setMin(Integer.parseInt(dataList.get(i), 16));
                i++;
                entity.setSecond(Integer.parseInt(dataList.get(i), 16));
                save(entity);
                //结果数据
            } else if (StringUtils.equals(ZhjdIotUtils.DATA_TYPE_RES, dataList.get(i))) {
                AsphaltCombustionFurnaceResEntity resEntity = new AsphaltCombustionFurnaceResEntity();
                resEntity.setId(currentMap.get(deviceId));
                currentMap.remove(deviceId);
                resEntity.setDeviceId(deviceId);
                resEntity.setOriginalData(resData);
                resEntity.setCreateTime(nowDate);

                // 将16进制转换为10进制数据，不含（0x）
                // 初始重量WEIGHT1，4字节无符号数，高字节在前，单位g，包括1位小数；
                i++;
                String originalWeight = "" + Integer.parseInt(dataList.get(i), 16) + Integer.parseInt(dataList.get(i + 1), 16) + Integer.parseInt(dataList.get(i + 2), 16) + Integer.parseInt(dataList.get(i + 3), 16);
                resEntity.setOriginalWeight(ZhjdIotUtils.subByDecimalPlaces(1, originalWeight));

                //实时重量WEIGHT2，4字节无符号数，高字节在前，单位g，包括1位小数；
                i += 4;
                String realTimeWeight = "" + Integer.parseInt(dataList.get(i), 16) + Integer.parseInt(dataList.get(i + 1), 16) + Integer.parseInt(dataList.get(i + 2), 16) + Integer.parseInt(dataList.get(i + 3), 16);
                resEntity.setRealTimeWeight(ZhjdIotUtils.subByDecimalPlaces(1, realTimeWeight));

                i += 2;
                String realTimeTemp = "" + Integer.parseInt(dataList.get(i), 16) + Integer.parseInt(dataList.get(i + 1), 16);
                resEntity.setRealTimeTemp(ZhjdIotUtils.subByDecimalPlaces(1, realTimeTemp));

                i += 2;
                resEntity.setMin(Integer.parseInt(dataList.get(i), 16));
                i++;
                resEntity.setSecond(Integer.parseInt(dataList.get(i), 16));

                asphaltCombustionFurnaceResService.saveOrUpdate(resEntity);
            } else {
                throw new RenException("燃烧法沥青含量测定仪（燃烧炉）数据解析异常：" + resData);
            }
        } catch (Exception e) {
            errorRecordService.saveErrorData(ZhjdIotUtils.ASPHALT_COMBUSTION_FURNACE, deviceId, resData);
            throw new RenException("数据解析异常");
        }
    }

    // +++++++++++++++++++++++ 文双 ++++++++++++++++++ //

}
